package com.duanjc.doc.es.service.impl;

import com.duanjc.doc.es.controller.dto.ResponseData;
import com.duanjc.doc.es.controller.dto.Result;
import com.duanjc.doc.es.dto.SearchParamDTO;
import com.duanjc.doc.es.entity.WikiPageEsContent;
import com.duanjc.doc.es.repository.WikiPageContentRepository;
import com.duanjc.doc.es.service.WikiPageContentEsService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.elasticsearch.index.query.QueryBuilders.multiMatchQuery;

/**
 * [一句话描述该类的功能]
 *
 * @author : [duanjiangcheng]
 * @version : [v1.0]
 * @createTime : [2023/6/28 18:58]
 */
@Slf4j
@Service
public class WikiPageContentEsServiceImpl implements WikiPageContentEsService {

    @Autowired
    private WikiPageContentRepository wikiPageContentRepository;

    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    /**
     * description: 保存文档 <br>
     * version: 1.0 <br>
     * date: 2023/6/28 18:56 <br>
     * author: duanjiangcheng <br>
     *
     * @param wikiPageEsContent WikiPageContent
     * @return String
     */
    @Override
    public String saveWikiPageContent(WikiPageEsContent wikiPageEsContent) {
        WikiPageEsContent w = wikiPageContentRepository.save(wikiPageEsContent);
        return w.getId();
    }

    /**
     * description: 删除文档 <br>
     * version: 1.0 <br>
     * date: 2023/6/28 18:57 <br>
     * author: duanjiangcheng <br>
     *
     * @param wikiPageEsContent WikiPageContent
     * @return void
     */
    @Override
    public void deleteWikiPageContent(WikiPageEsContent wikiPageEsContent) {
        wikiPageContentRepository.delete(wikiPageEsContent);
    }

    /**
     * description: 修改文档 <br>
     * version: 1.0 <br>
     * date: 2023/6/28 18:58 <br>
     * author: duanjiangcheng <br>
     *
     * @param wikiPageEsContent WikiPageContent
     * @return String
     */
    @Override
    public String updateWikiPageContent(WikiPageEsContent wikiPageEsContent) {
        WikiPageEsContent w = wikiPageContentRepository.save(wikiPageEsContent);
        return w.getId();
    }

    /**
     * description: 查询文档数据 <br>
     * version: 1.0 <br>
     * date: 2023/6/28 19:41 <br>
     * author: duanjiangcheng <br>
     *
     * @param searchParamDTO SearchParamDTO
     * @return java.util.List<com.duanjc.doc.es.entity.WikiPageContent>
     */
    @Override
    public Result<List<WikiPageEsContent>> searchWikiPageContent(SearchParamDTO searchParamDTO) {
        WikiPageEsContent wikiPageEsContent = new WikiPageEsContent();
        wikiPageEsContent.setContent(searchParamDTO.getContent());
        int pageNo = searchParamDTO.getPageNo();
        int pageSize = searchParamDTO.getPageSize();
        //分页
        Pageable pageable = PageRequest.of(pageNo - 1, pageSize);

        List<WikiPageEsContent> wikiPageEsContentArrayList = new ArrayList<>();
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(multiMatchQuery(wikiPageEsContent.getContent(), "content", "preview", "name"))
                .withHighlightFields(new HighlightBuilder.Field("content"), new HighlightBuilder.Field("preview"), new HighlightBuilder.Field("name"))
                .withHighlightBuilder(new HighlightBuilder().preTags("<font style='color: red;'>").postTags("</font>"))
                .withPageable(pageable)
                .build();

        SearchHits<WikiPageEsContent> search = elasticsearchRestTemplate.search(searchQuery, WikiPageEsContent.class);
        for (SearchHit<WikiPageEsContent> searchHit : search) {
            WikiPageEsContent content = searchHit.getContent();
            //将高亮的字段取出来
            //高亮的内容
            Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
            //将高亮的内容填充到content中
            content.setName(highlightFields.get("name") == null ? searchHit.getContent().getName() : highlightFields.get("name").get(0));
            content.setContent(highlightFields.get("content") == null ? searchHit.getContent().getContent() : highlightFields.get("content").get(0));
            content.setPreview(highlightFields.get("preview") == null ? searchHit.getContent().getPreview() : highlightFields.get("preview").get(0));
            wikiPageEsContentArrayList.add(content);
            log.info(content.getName());
        }
        log.info("查询出：{} 条数据.", wikiPageEsContentArrayList.size());
        Result<List<WikiPageEsContent>> result = ResponseData.success(wikiPageEsContentArrayList);
        Map<String,Object> map = new HashMap<>();
        map.put("total", search.getTotalHits());
        result.setMapdata(map);
        return result;
    }


    /**
     * description: 查询所有文档 <br>
     * version: 1.0 <br>
     * date: 2023/6/28 18:58 <br>
     * author: duanjiangcheng <br>
     *
     * @return java.util.List<com.duanjc.doc.es.entity.WikiPageContent>
     */
    @Override
    public List<WikiPageEsContent> getAllWikiPageContent() {
        return null;
    }

    @Override
    public void deleteAllWikiPageContent() {

    }

    @Override
    public void createIndex() {

    }

    @Override
    public void deletIndex() {

    }

    @Override
    public void updatePageBatch(List<WikiPageEsContent> list) {
        try {
            wikiPageContentRepository.saveAll(list);
        } catch (Exception e) {
            log.error("插入过程中报错.", e);
        }
    }

    @Override
    public void deleteById(String id) {
        wikiPageContentRepository.deleteById(id);
    }
}
